package com.guosen.zebra.framework.starter.sso.autoconfigure;

import com.guosen.zebra.framework.starter.sso.handler.SsoLoginHandler;
import com.guosen.zebra.framework.starter.sso.properties.SsoProperties;
import com.guosen.zebra.framework.starter.sso.service.SsoCallBackService;
import com.guosen.zebra.framework.starter.sso.service.SsoService;
import com.guosen.zebra.framework.starter.sso.service.SsoSupportService;
import com.guosen.zebra.framework.starter.sso.service.impl.DefaultSsoCallBackService;
import com.guosen.zebra.framework.starter.sso.service.impl.SsoServiceImpl;
import com.guosen.zebra.framework.starter.sso.service.impl.SsoSupportServiceImpl;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.web.servlet.function.RequestPredicate;
import org.springframework.web.servlet.function.RouterFunction;
import org.springframework.web.servlet.function.RouterFunctions;
import org.springframework.web.servlet.function.ServerResponse;

import static org.springframework.web.servlet.function.RequestPredicates.accept;


@Configuration(proxyBeanMethods = false)
@EnableConfigurationProperties(SsoProperties.class)
public class SsoAutoConfiguration {

    private static final RequestPredicate ACCEPT_JSON = accept(MediaType.APPLICATION_JSON);


    @Bean
    @ConditionalOnMissingBean(SsoCallBackService.class)
    public SsoCallBackService ssoCallBackService() {
        return new DefaultSsoCallBackService();
    }


    @Bean
    public SsoSupportService ssoSupportService(SsoProperties ssoProperties) {
        return new SsoSupportServiceImpl(ssoProperties);
    }

    @Bean
    public SsoLoginHandler ssoLoginHandler(SsoProperties ssoProperties, SsoService ssoService, SsoSupportService ssoSupportService,
                                           SsoCallBackService ssoCallBackService) {
        return new SsoLoginHandler(ssoProperties, ssoService, ssoSupportService, ssoCallBackService);
    }

    @Bean
    public RouterFunction<ServerResponse> ssoRouterFunction(SsoProperties ssoProperties, SsoLoginHandler ssoLoginHandler) {
        return RouterFunctions.route()
                .GET(ssoProperties.getSsoLoginPath(), ACCEPT_JSON, ssoLoginHandler::ssoLogin)
                .POST(ssoProperties.getSsoReturnPath(), ACCEPT_JSON, ssoLoginHandler::ssoReturn)
                .build();
    }

    @Bean
    public SsoService ssoService(SsoProperties ssoProperties, SsoCallBackService ssoCallBackService, SsoSupportService ssoSupportService) {
        return new SsoServiceImpl(ssoProperties, ssoCallBackService, ssoSupportService);
    }
}
